# coding=utf-8
# n = 123
# f = 456.789
# s1 = 'Hello, world'
# s2 = 'Hello, \'Adam\'\n'
# s3 = r'Hello, "Bart"'
#
# s4 = r'''Hello,
#
# Bob!'''
#
# print(n, f, s1, s2, s3, s4)
# print("%02d-%02d" % (3, 1))

# s1 = 72
# s2 = 85
# r = (s2 - s1) / s1 * 100
# print(f"{r:.1f}%")
# L = [
#     ['Apple', 'Google', 'Microsoft'],
#     ['Java', 'Python', 'Ruby', 'PHP'],
#     ['Adam', 'Bart', 'Bob']
# ]
# print(L[0][0], L[1][1], L[2][2])
# age = 20
# if age >= 18:
#     print('adult')
# else:
#     print('teenager')
# height = 1.70
# weight = 72
# bmi = weight / height ** 2
# if bmi > 32:
#     print('严重肥胖')
# elif bmi > 28:
#     print('肥胖')
# elif bmi > 25:
#     print('过重')
# elif bmi > 18.5:
#     print('正常')
# else:
#     print('过轻')
# n1 = 255
# n2 = 1000


# print(str(hex(n1)), hex(n2))
# n = (1, 2, 3)
# import math
#
#
# def q(a, b, c):
#     d = b ** 2 - 4 * a * c
#     if d < 0:
#         return "无解"
#     return (-b + math.sqrt(d)) / (2 * a), (-b - math.sqrt(d)) / (2 * a)
#
#
# print(q(1, 3, -4))

# def person(name, age, *, city, job):
#     print(name, age, city, job)
#
#
# def move(n, a, b, c):
#     if n == 1:
#         print(a, '-->', c)
#     else:
#         move(n - 1, a, c, b)
#         move(1, a, b, c)
#         move(n - 1, b, a, c)


# def trim(s):
#     if len(s) == 0:
#         return ''
#     i = 0
#     j = len(s) - 1
#     while s[i] == ' ' and i < j:
#         i += 1
#     while s[j] == ' ' and i < j:
#         j -= 1
#     if i == j:
#         return ''
#     return s[i:j + 1]
#
#
# # 测试:
# if trim('hello  ') != 'hello':
#     print('测试失败!')
# elif trim('  hello') != 'hello':
#     print('测试失败!')
# elif trim('  hello  ') != 'hello':
#     print('测试失败!')
# elif trim('  hello  world  ') != 'hello  world':
#     print('测试失败!')
# elif trim('') != '':
#     print('测试失败!')
# elif trim('    ') != '':
#     print('测试失败!')
# else:
#     print('测试成功!')

# def findMinAndMax(L):
#     if len(L) == 0:
#         return None, None
#     min_value = L[0]
#     max_value = L[0]
#     for i in L:
#         if i < min_value:
#             min_value = i
#         if i > max_value:
#             max_value = i
#     return min_value, max_value
#
#
# # 测试
# if findMinAndMax([]) != (None, None):
#     print('测试失败!')
# elif findMinAndMax([7]) != (7, 7):
#     print('测试失败!')
# elif findMinAndMax([7, 1]) != (1, 7):
#     print('测试失败!')
# elif findMinAndMax([7, 1, 3, 9, 5]) != (1, 9):
#     print('测试失败!')
# else:
#     print('测试成功!')
# L1 = ['Hello', 'World', 18, 'Apple', None]
# L2 = [s.lower() for s in L1 if isinstance(s, str)]
# # 测试:
# print(L2)
# if L2 == ['hello', 'world', 'apple']:
#     print('测试通过!')
# else:
#     print('测试失败!')
# def triangles():
#     L = [1]
#     while True:
#         yield L
#         L = [1] + [L[i] + L[i + 1] for i in range(len(L) - 1)] + [1]
#
#
# n = 0
# results = []
# for t in triangles():
#     results.append(t)
#     n = n + 1
#     if n == 10:
#         break
#
# for t in results:
#     print(t)
#
# if results == [
#     [1],
#     [1, 1],
#     [1, 2, 1],
#     [1, 3, 3, 1],
#     [1, 4, 6, 4, 1],
#     [1, 5, 10, 10, 5, 1],
#     [1, 6, 15, 20, 15, 6, 1],
#     [1, 7, 21, 35, 35, 21, 7, 1],
#     [1, 8, 28, 56, 70, 56, 28, 8, 1],
#     [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
# ]:
#     print('测试通过!')
# else:
#     print('测试失败!')
# import math

# def inf_gener():
#     num = 1
#     while True:
#         yield num1
#         num += 1
#
#
# for n in inf_gener():
#     print(n)
# def normalize(name):
#     name = name[0].upper() + name[1:].lower()
#     return name
#
#
# # 测试:
# L1 = ['adam', 'LISA', 'barT']
# L2 = list(map(normalize, L1))
# print(L2)
# from functools import reduce
#
#
# def prod(L):
#     def mul(x, y):
#         return x * y
#
#     return reduce(mul, L)
#
#
# print('3 * 5 * 7 * 9 =', prod([3, 5, 7, 9]))
# if prod([3, 5, 7, 9]) == 945:
#     print('测试成功!')
# else:
#     print('测试失败!')

# from functools import reduce


# digits = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '.': '.'}

# def str2float(s):
#     def get_num(ch):
#         return digits[ch]

# def str2float(L):
#     int = 0
#     float = 0.0
#     for num in L:
#         if num == '.':
#             break
#         int = int * 10 + digits[num]
#     for item in reversed(L):
#         if item == '.':
#             break
#         float = (float + digits[item]) / 10
#     return int + float

# reduce(to_float, map(get_num, s))
# return to_float(s)

# def str2float(s):
#     def get_num(ch):
#         return digits[ch]
#
#     L = list(map(get_num, s))
#     L1 = []  # 整数部分
#     L2 = []  # 小数部分
#     for k, v in enumerate(L):
#         if v == '.':
#             L1 = L[:k]
#             L2 = L[k + 1:]
#             break
#
#     def to_int(x, y):
#         return x * 10 + y
#
#     def to_float(x, y):
#         return x / 10 + y
#
#     return reduce(to_int, L1) + 0.1 * reduce(to_float, reversed(L2))
#
#
# print('str2float(\'123.456\') =', str2float('123.456'))
# if abs(str2float('123.456') - 123.456) < 0.00001:
#     print('测试成功!')
# else:
#     print('测试失败!')
# def _odd_iter():
#     n = 1
#     while True:
#         n = n + 2
#         yield n
#
#
# it = _odd_iter()
# print(it)
# def is_palindrome(n):
#     n = str(n)
#     return n == n[::-1]
#
#
# # 测试:
# output = filter(is_palindrome, range(1, 1000))
# print('1~1000:', list(output))
# if list(filter(is_palindrome, range(1, 200))) == [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101,
#                                                   111, 121, 131, 141, 151, 161, 171, 181, 191]:
#     print('测试成功!')
# else:
#     print('测试失败!')
# L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
#
#
# def by_name(t):
#     return t[0].lower()
#
#
# def by_score(t):
#     return t[1]
#
#
# L2 = sorted(L, key=by_score)
# print(L2)

# class Student(object):
#     def __init__(self, name, gender):
#         self.name = name
#         self.__gender = gender
#
#     def get_gender(self):
#         return self.__gender
#
#     def set_gender(self, gender):
#         self.__gender = gender
#
#
# # 测试:
# bart = Student('Bart', 'male')
# if bart.get_gender() != 'male':
#     print('测试失败!')
# else:
#     bart.set_gender('female')
#     if bart.get_gender() != 'female':
#         print('测试失败!')
#     else:
#         print('测试成功!')
# print(bart.__gender)


# class Student(object):
#     count = 0
#
#     def __init__(self, name):
#         self.name = name
#         Student.count += 1
#
#
# # 测试:
# if Student.count != 0:
#     print('测试失败!')
# else:
#     bart = Student('Bart')
#     if Student.count != 1:
#         print('测试失败!')
#     else:
#         lisa = Student('Bart')
#         if Student.count != 2:
#             print('测试失败!')
#         else:
#             print('Students:', Student.count)
#             print('测试通过!')
# class Screen(object):
#     @property
#     def width(self):
#         return self._width
#
#     @width.setter
#     def width(self, width):
#         self._width = width
#
#     @property
#     def height(self):
#         return self._height
#
#     @height.setter
#     def height(self, height):
#         self._height = height
#
#     @property
#     def resolution(self):
#         return self._width * self._height
#
#
# # 测试:
# s = Screen()
# s.width = 1024
# s.height = 768
# print('resolution =', s.resolution)
# if s.resolution == 786432:
#     print('测试通过!')
# else:
#     print('测试失败!')

# class Chain(object):
#     def __init__(self, path=''):
#         self._path = path
#
#     def __getattr__(self, path):
#         return Chain('%s/%s' % (self._path, path))
#
#     def __str__(self):
#         return self._path
#     #
#     # __repr__ = __str__
#
#
# print(Chain().status.user.timeline.list)

# from functools import reduce
#
#
# def str2num(s):
#     return int(s)
#
#
# def calc(exp):
#     ss = exp.split('+')
#     ns = map(str2num, ss)
#     return reduce(lambda acc, x: acc + x, ns)
#
#
# import unittest
#
#
# class Student(object):
#     def __init__(self, name, score):
#         self.name = name
#         self.score = score
#
#     def get_grade(self):
#         if self.score < 0 or self.score > 100:
#             raise ValueError('bad score')
#         if self.score >= 80:
#             return 'A'
#         if self.score >= 60:
#             return 'B'
#         return 'C'
#
#
# class TestStudent(unittest.TestCase):
#
#     def test_80_to_100(self):
#         s1 = Student('Bart', 80)
#         s2 = Student('Lisa', 100)
#         self.assertEqual(s1.get_grade(), 'A')
#         self.assertEqual(s2.get_grade(), 'A')
#
#     def test_60_to_80(self):
#         s1 = Student('Bart', 60)
#         s2 = Student('Lisa', 79)
#         self.assertEqual(s1.get_grade(), 'B')
#         self.assertEqual(s2.get_grade(), 'B')
#
#     def test_0_to_60(self):
#         s1 = Student('Bart', 0)
#         s2 = Student('Lisa', 59)
#         self.assertEqual(s1.get_grade(), 'C')
#         self.assertEqual(s2.get_grade(), 'C')
#
#     def test_invalid(self):
#         s1 = Student('Bart', -1)
#         s2 = Student('Lisa', 101)
#         with self.assertRaises(ValueError):
#             s1.get_grade()
#         with self.assertRaises(ValueError):
#             s2.get_grade()
#
#
# if __name__ == '__main__':
#     unittest.main()
# fpath = 'test.txt'
#
# with open(fpath, 'r') as f:
#     s = f.read()
#     print(s)

# 运行代码观察结果


# import subprocess
# import os

# from multiprocessing import Process, Queue
# import os, time, random
#
#
# # 写数据进程执行的代码:
# def write(q):
#     print('Process to write: %s' % os.getpid())
#     for value in ['A', 'B', 'C']:
#         print('Put %s to queue...' % value)
#         q.put(value)
#         time.sleep(random.random())
#
#
# # 读数据进程执行的代码:
# def read(q):
#     print('Process to read: %s' % os.getpid())
#     while True:
#         value = q.get(True)
#         print('Get %s from queue.' % value)
#
#
# if __name__ == '__main__':
#     # 父进程创建Queue，并传给各个子进程：
#     q = Queue()
#     pw = Process(target=write, args=(q,))
#     pr = Process(target=read, args=(q,))
#     # 启动子进程pw，写入:
#     pw.start()
#     # 启动子进程pr，读取:
#     pr.start()
#     # 等待pw结束:
#     pw.join()
#     # pr进程里是死循环，无法等待其结束，只能强行终止:
#     pr.terminate()
# task_master.py
#
# import random, time, queue
# from multiprocessing.managers import BaseManager
#
# # 发送任务的队列:
# task_queue = queue.Queue()
# # 接收结果的队列:
# result_queue = queue.Queue()
#
#
# # 从BaseManager继承的QueueManager:
# class QueueManager(BaseManager):
#     pass
#
#
# # 把两个Queue都注册到网络上, callable参数关联了Queue对象:
# QueueManager.register('get_task_queue', callable=lambda: task_queue)
# QueueManager.register('get_result_queue', callable=lambda: result_queue)
# # 绑定端口5000, 设置验证码'abc':
# manager = QueueManager(address=('', 5000), authkey=b'abc')
# # 启动Queue:
# manager.start()
# # 获得通过网络访问的Queue对象:
# task = manager.get_task_queue()
# result = manager.get_result_queue()
# # 放几个任务进去:
# for i in range(10):
#     n = random.randint(0, 10000)
#     print('Put task %d...' % n)
#     task.put(n)
# # 从result队列读取结果:
# print('Try get results...')
# for i in range(10):
#     r = result.get(timeout=10)
#     print('Result: %s' % r)
# # 关闭:
# manager.shutdown()
# print('master exit.')
# import re
#
# # if re.match(r'^\d{3}-\d{3,8}$', '010-12345'):
# #     print('match')
# # else:
# #     print('not match')
# # # ret = re.findall(r'[\s,;?!a]+', 'a,b ; ; c  d')
# ret = re.match(r'(0*)$', '000000000000').groups()
# print(ret)

# import re
#
#
# def is_valid_email(addr):
#     if re.match(r'^[a-zA-Z0-9._]+@[a-zA-Z0-9._]+(\.com)$', addr):
#         return True
#     return False
#
#
# # 测试:
# assert is_valid_email('someone@gmail.com')
# assert is_valid_email('bill.gates@microsoft.com')
# assert not is_valid_email('bob#example.com')
# assert not is_valid_email('mr-bob@example.com')
# print('ok')
# import re
#
#
# def name_of_email(addr):
#     if '<' and '>' in addr:
#         name = re.match(r'<(.*)>', addr)
#     else:
#         name = re.match(r'(\w+)@.*', addr)
#     return name.group(1)
#
#
# # print(name_of_email('<Tom Paris> tom@voyager.org'))
# # 测试:
# # assert name_of_email('<Tom Paris> tom@voyager.org') == 'Tom Paris'
# # assert name_of_email('tom@voyager.org') == 'tom'
# print(re.IGNORECASE)

# import re
# from datetime import datetime, timezone, timedelta
#
#
# def to_timestamp(dt_str, tz_str):
#     dt = datetime.strptime(dt_str, '%Y-%m-%d %H:%M:%S')
#     uct = re.match(r'UTC([+-]\d+):00', tz_str).groups()
#     if uct:
#         tz = timezone(timedelta(hours=int(uct[0])))
#         timestamp = dt.replace(tzinfo=tz).timestamp()
#         return timestamp
#     else:
#         raise ValueError('timezone error')
#
#
# # 测试
# t1 = to_timestamp('2015-6-1 08:10:30', 'UTC+7:00')
# assert t1 == 1433121030.0, t1
# t2 = to_timestamp('2015-5-31 16:10:30', 'UTC-09:00')
# assert t2 == 1433121030.0, t2
# print('ok')
# import itertools
#
#
# #
# #
# def pi(N):
#     ' 计算pi的值 '
#     # step 1: 创建一个奇数序列: 1, 3, 5, 7, 9, ...
#     odds = itertools.count(1, 2)
#
#     # step 2: 取该序列的前N项: 1, 3, 5, 7, 9, ..., 2*N-1.
#     n_odds = itertools.takewhile(lambda x: x <= 2 * N, odds)
#     # step 3: 添加正负符号并用4除: 4/1, -4/3, 4/5, -4/7, 4/9, ...
#     # p_odds = map(lambda x: -4 / x if x % 2 == 0 else 4 / x, n_odds)
#     # p_odds = map(lambda item: 4 / item[1] if item[0] % 2 == 0 else -4 / item[1],
#     #              enumerate(n_odds))
#     p_odds = (4 / x if i % 2 == 0 else -4 / x for i, x in enumerate(n_odds))
#     # step 4: 求和:
#
#     return sum(p_odds)
#
#
# # 测试:
# print(pi(10))
# print(pi(100))
# print(pi(1000))
# print(pi(1000000000))
# assert 3.04 < pi(10) < 3.05
# assert 3.13 < pi(100) < 3.14
# assert 3.140 < pi(1000) < 3.141
# assert 3.1414 < pi(10000) < 3.1415
# print('ok')
# from tkinter import *
#
#
# class Application(Frame):
#     def __init__(self, master=None):
#         Frame.__init__(self, master)
#         self.pack()
#         self.createWidgets()
#
#     def createWidgets(self):
#         self.helloLabel = Label(self, text='Hello, world!')
#         self.helloLabel.pack()
#         self.quitButton = Button(self, text='Quit', command=self.quit)
#         self.quitButton.pack()
#
#
# app = Application()
# # 设置窗口标题:
# app.master.title('Hello World')
# # 主消息循环:
# app.mainloop()
# from tkinter import *
# import tkinter.messagebox as messagebox
#
#
# class Application(Frame):
#     def __init__(self, master=None):
#         Frame.__init__(self, master)
#         self.pack()
#         self.createWidgets()
#
#     def createWidgets(self):
#         self.nameInput = Entry(self)
#         self.nameInput.pack()
#         self.alertButton = Button(self, text='Hello', command=self.hello)
#         self.alertButton.pack()
#
#     def hello(self):
#         name = self.nameInput.get() or 'world'
#         messagebox.showinfo('Message', 'Hello, %s' % name)
#
#
# app = Application()
# # 设置窗口标题:
# app.master.title('Hello World')
# # 主消息循环:
# app.mainloop()
#
# # 导入turtle包的所有内容:
# from turtle import *
#
# # 设置笔刷宽度:
# width(4)
#
# # 前进:
# forward(200)
# # 右转90度:
# right(90)
#
# # 笔刷颜色:
# pencolor('red')
# forward(100)
# right(90)
#
# pencolor('green')
# forward(200)
# right(90)
#
# pencolor('blue')
# forward(100)
# right(90)
#
# # 调用done()使得窗口等待被关闭，否则将立刻关闭窗口:
# done()
# from turtle import *
#
#
# def drawStar(x, y):
#     pu()
#     goto(x, y)
#     pd()
#     # set heading: 0
#     seth(0)
#     for i in range(5):
#         fd(40)
#         rt(144)
#
#
# for x in range(0, 250, 50):
#     drawStar(x, 0)
#
# done()
# import torch
#
# attention_mask_with_indices = torch.tensor([[1, 1, 2, 2, 2, 0]])
#
# # 步骤1: 创建非填充掩码
# non_padding_mask = (attention_mask_with_indices != 0)  # [[True, True, True, True, True, False]]
# print(non_padding_mask.unsqueeze(1))
# print(non_padding_mask.unsqueeze(1).unsqueeze(2))
# non_padding_mask = non_padding_mask.unsqueeze(1).unsqueeze(2)  # [1, 1, 1, 6]
# print(non_padding_mask)


def log1(func):
    print('call %s():' % func.__name__)
    return func


def log2(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)

    return wrapper


def log3(name):
    def decorator(func):
        def wrapper(*args, **kw):
            print('call %s():' % name)
            return func(*args, **kw)

        return wrapper

    return decorator


@log3('name')  # now = log3('name')(now)
def now():
    print('now')


import torch

now()
print(torch.cuda.is_available())
